﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using StructureMap;
using MethodWorx.CMS.Plugins;
using MethodWorx.CMS.Administration;
using MethodWorx.CMS.UI.Controllers;

namespace MethodWorx.CMS.UI.Application
{
    public class StructureMapControllerFactory : DefaultControllerFactory
    {
        public override IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName)
        {
            if (controllerName == "Plugin")
            {
                //
                //  ok we made it here
                //  so lets load the plugin
                Guid id = Guid.Parse(requestContext.RouteData.Values["extensionId"].ToString());
                PluginFactory factory = new PluginFactory(
                    ObjectFactory.GetInstance<IApplicationSettingsRepository>(), 
                    ObjectFactory.GetInstance<IPluginRepository>());

                IdeExtension extension = factory.GetIdeExtension(id);

                if (extension != null)
                {
                    requestContext.HttpContext.Items["__currentIdeExtension"] = extension;

                    var controller = (IController)ObjectFactory
                        .With<IdeExtension>(extension)
                        .GetInstance(extension.Controller);

                    return controller;
                }
                else
                {
                    return new PluginDisabledOrMissingController();
                }
            }
            else if (controllerName == "GlobalPlugin")
            {
                //
                //  ok we made it here
                //  so lets load the plugin
                Guid id = Guid.Parse(requestContext.RouteData.Values["extensionId"].ToString());
                PluginFactory factory = new PluginFactory(
                    ObjectFactory.GetInstance<IApplicationSettingsRepository>(),
                    ObjectFactory.GetInstance<IPluginRepository>());

                IdeExtension extension = factory.GetIdeExtension(id);

                if (extension != null)
                {
                    requestContext.HttpContext.Items["__currentIdeExtension"] = extension;

                    var controller = (IController)ObjectFactory
                        .With<IdeExtension>(extension)
                        .GetInstance(extension.Controller);

                    return controller;
                }
                else
                {
                    return new PluginDisabledOrMissingController();
                }
            }
            else
                return base.CreateController(requestContext, controllerName);
        }

        protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
        {
            try
            {
                if (controllerType != null)
                    return (IController)ObjectFactory.GetInstance(controllerType);
                else
                    return base.GetControllerInstance(requestContext, controllerType);
            }
            catch (Exception ex)
            {
                //
                //  ok, we are previewing a page, which means
                //  that any url that comes in needs to be dealt with as virtual
                //  URL
                bool processed = false;
                foreach (SafePlugin plugin in ObjectFactory.GetInstance<PluginFactory>().GetRequestPlugins())
                {
                    //
                    //  ok, process
                    processed = plugin.Invoke<IRequestPlugin, bool>(p => p.ProcessRequest(new HttpContextWrapper(HttpContext.Current)));
                    if (processed)
                        break;
                }
                if (!processed)
                    throw;
                else
                {
                    HttpContext.Current.Response.End();
                    return null;
                }

            }
        }
    }
}
